package com.google.code.sms.ajax;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;

import com.google.code.sms.service.SettingsService;
import org.directwebremoting.WebContextFactory;

import com.google.code.sms.domain.MediaElement;
import com.google.code.sms.domain.Playlist;
import com.google.code.sms.service.MediaElementService;
import com.google.code.sms.service.SecurityService;

/**
 * Provides AJAX-enabled services for manipulating playlists. This class is used
 * by the DWR framework (http://getahead.ltd.uk/dwr/).
 *
 * @author Sindre Mehus
 */
public class PlaylistService {

    private MediaElementService mediaElementService;
    private SecurityService securityService;
    private com.google.code.sms.service.PlaylistService playlistService;
    private SettingsService settingsService;

    public List<Playlist> getReadablePlaylists() {
        HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
        String username = securityService.getCurrentUsername(request);
        return playlistService.getReadablePlaylistsForUser(username);
    }

    public List<Playlist> getWritablePlaylists() {
        HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
        String username = securityService.getCurrentUsername(request);
        return playlistService.getWritablePlaylistsForUser(username);
    }

    public PlaylistInfo getPlaylist(int id) {
        HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();

        Playlist playlist = playlistService.getPlaylist(id);
        List<MediaElement> elements = playlistService.getElementsInPlaylist(id);

        String username = securityService.getCurrentUsername(request);
        return new PlaylistInfo(playlist, createEntries(elements));
    }

    public List<Playlist> createEmptyPlaylist() {
        HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
        Locale locale = settingsService.getLocale();
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, locale);

        Date now = new Date();
        Playlist playlist = new Playlist();
        playlist.setUsername(securityService.getCurrentUsername(request));
        playlist.setCreated(now);
        playlist.setChanged(now);
        playlist.setPublic(false);
        playlist.setName(dateFormat.format(now));

        playlistService.createPlaylist(playlist);
        return getReadablePlaylists();
    }

    public void appendToPlaylist(int playlistId, List<Integer> mediaElementIds) {
        List<MediaElement> elements = playlistService.getElementsInPlaylist(playlistId);
        for (Integer mediaElementId : mediaElementIds) {
            MediaElement element = mediaElementService.getMediaElement(mediaElementId);
            if (element != null) {
                elements.add(element);
            }
        }
        playlistService.setElementsInPlaylist(playlistId, elements);
    }

    private List<PlaylistInfo.Entry> createEntries(List<MediaElement> elements) {
        List<PlaylistInfo.Entry> result = new ArrayList<>();
        for (MediaElement element : elements) {
            result.add(new PlaylistInfo.Entry(element.getId(), element.getMetaData().getTitle(), element.getMetaData().getArtist(), element.getMetaData().getAlbum(),
                    element.getMetaData().getDurationAsString()));
        }

        return result;
    }

    public PlaylistInfo remove(int id, int index) {
        List<MediaElement> elements = playlistService.getElementsInPlaylist(id);
        elements.remove(index);
        playlistService.setElementsInPlaylist(id, elements);
        return getPlaylist(id);
    }

    public PlaylistInfo up(int id, int index) {
        List<MediaElement> elements = playlistService.getElementsInPlaylist(id);
        if (index > 0) {
            MediaElement element = elements.remove(index);
            elements.add(index - 1, element);
            playlistService.setElementsInPlaylist(id, elements);
        }
        return getPlaylist(id);
    }

    public PlaylistInfo down(int id, int index) {
        List<MediaElement> elements = playlistService.getElementsInPlaylist(id);
        if (index < elements.size() - 1) {
            MediaElement element = elements.remove(index);
            elements.add(index + 1, element);
            playlistService.setElementsInPlaylist(id, elements);
        }
        return getPlaylist(id);
    }

    public void deletePlaylist(int id) {
        playlistService.deletePlaylist(id);
    }

    public PlaylistInfo updatePlaylist(int id, String name, boolean isPublic) {
        Playlist playlist = playlistService.getPlaylist(id);
        playlist.setName(name);
        playlist.setPublic(isPublic);
        playlistService.updatePlaylist(playlist);
        return getPlaylist(id);
    }

    public void setPlaylistService(com.google.code.sms.service.PlaylistService playlistService) {
        this.playlistService = playlistService;
    }

    public void setSecurityService(SecurityService securityService) {
        this.securityService = securityService;
    }

    public void setMediaElementService(MediaElementService mediaElementService) {
        this.mediaElementService = mediaElementService;
    }

    public void setSettingsService(SettingsService settingsService) {
        this.settingsService = settingsService;
    }
}